package com.hx.ycy.web.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * Created by hx-pc on 16-11-1.
 */
public abstract class WebSocketPool extends Pool<Session> {

    protected Logger LOGGER = LoggerFactory.getLogger(getClassName());
    private static int onlineCount;
    public static ExecutorService singleThreadExecutor;
    private static ObjectMapper objectMapper;

    static {
        onlineCount = 0;
        singleThreadExecutor = Executors.newSingleThreadExecutor();
        objectMapper = new ObjectMapper();
    }

    protected Class getClassName() {
        return this.getClass();
    }

    public void onOpen(Session session) {
        this.append(session);
        addOnlineCount();
        LOGGER.info("有新链接加入!当前在线人数为{}", getOnlineCount());
    }

    public void onClose(Session session) {
        this.remove(session);
        subOnlineCount();
        LOGGER.info("有一链接关闭!当前在线人数为{}", getOnlineCount());
    }

    public void onMessage(Session session, String message){
        LOGGER.info("来自客户端的消息:{}", message);
        Response response = new Response();
        response.setMessage(message);
        sendApiUpdateMessageAll(response);
    }

    public void sendApiUpdateMessageAll(Response response) {
        this.getSingleThreadExecutor().submit((Runnable) () -> {
            for (int i = 0; i < getAsyncPool().size(); i++) {
                try {
                    getAsyncPool().get(i).getBasicRemote().sendText(objectMapper.writeValueAsString(response));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void sendApiUpdateMessageAllWithoutSelf(Response response, Session session) {
        this.getSingleThreadExecutor().submit(() -> {
            for (int i = 0; i < getAsyncPool().size(); i++) {
                if (!getAsyncPool().get(i).getId().equals(session.getId())) {
                    try {
                        getAsyncPool().get(i).getBasicRemote().sendText(objectMapper.writeValueAsString(response));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public void sendApiUpdateMessage(Response response, Session session) {
        this.getSingleThreadExecutor().submit(()->{
            try {
                session.getAsyncRemote().sendText(objectMapper.writeValueAsString(response));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    public int getOnlineCount() {
        return onlineCount;
    }

    public ExecutorService getSingleThreadExecutor() {
        return singleThreadExecutor;
    }

    public synchronized void addOnlineCount() {
        onlineCount++;
    }

    public synchronized void subOnlineCount() {
        onlineCount--;
    }

}
